package com.htfyun.ft.fragment.engineer;

import android.os.Bundle;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.htfyun.ft.R;
import com.htfyun.ft.agingtest.TestHardDiskRWManager;
import com.htfyun.ft.fragment.BaseFragment;
import com.htfyun.ft.utils.DebugLog;

import java.lang.reflect.Method;
import java.util.List;

public class FragmentHardDiskRW extends BaseFragment implements TestHardDiskRWManager.OnRWListener {

    private Button btnStart;
    private Button btnDelete;
    private Button btnClearTxt;
    private TextView txtShow;

    private Spinner spinnerSize;
    private Spinner spinnerCount;

    private TestHardDiskRWManager hardDiskRWManager;

    private volatile boolean isStarted = false;
    private final Object startLock = new Object();

    @Override
    protected int getLayoutRes() {
        return R.layout.fragment_engineer_hard_disk_rw;
    }

    @Override
    protected void onInitView(@Nullable Bundle savedInstanceState) {

        btnStart = (Button) findViewById(R.id.btnStart);
        btnDelete = (Button) findViewById(R.id.btnDelete);
        btnClearTxt = (Button) findViewById(R.id.btnClearTxt);
        txtShow = (TextView) findViewById(R.id.txtShow);

        spinnerSize = (Spinner) findViewById(R.id.spinnerSize);
        spinnerCount = (Spinner) findViewById(R.id.spinnerCount);

        txtShow.setMovementMethod(ScrollingMovementMethod.getInstance());

        hardDiskRWManager = new TestHardDiskRWManager(mContext);
        hardDiskRWManager.setOnRWListener(this);

        btnStart.setText(R.string.engineer_hard_disk_start);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isStarted) {
                    stopTest();
                } else {
                    startTest();
                }
            }
        });

        btnClearTxt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtShow.setText("");
            }
        });

        findViewById(R.id.btnGetTemp).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateTempLog();
            }
        });

        btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                btnStart.setEnabled(false);
                spinnerCount.setEnabled(false);
                spinnerSize.setEnabled(false);
                btnDelete.setEnabled(false);

                hardDiskRWManager.deleteWritten();

            }
        });

    }

    @Override
    protected void onVisible() {
        super.onVisible();
        txtShow.setText("");
    }

    @Override
    protected void onInvisible() {
        super.onInvisible();
        stopTest();
    }

    public void startTest() {

        synchronized (startLock) {
            if (isStarted) {
                return;
            }
            isStarted = true;
        }

        btnStart.setText(R.string.engineer_hard_disk_stop);

        String log = "RW start test...";
        updateText(log);

        spinnerCount.setEnabled(false);
        spinnerSize.setEnabled(false);
        btnDelete.setEnabled(false);


        int[] sizes = getResources().getIntArray(R.array.hd_rw_size_values);
        int[] counts = getResources().getIntArray(R.array.hd_rw_count_values);
        int sizeSelectedPos = spinnerSize.getSelectedItemPosition();
        int countSelectedPos = spinnerCount.getSelectedItemPosition();

        hardDiskRWManager.startTest(sizes[sizeSelectedPos], counts[countSelectedPos]);
    }

    public void stopTest() {

        synchronized (startLock) {
            isStarted = false;
        }

        hardDiskRWManager.stopTest();

        btnStart.setText(R.string.engineer_hard_disk_start);

        spinnerCount.setEnabled(true);
        spinnerSize.setEnabled(true);
        btnDelete.setEnabled(true);

    }

    private void updateText(String log) {
        if (getActivity() == null) {
            return;
        }
        final String theLog = log;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                String text = txtShow.getText().toString();
                if (text.length() > 4096 * 4) {
                    txtShow.setText("");
                    text = "";
                }
                text += theLog + "\n";
                txtShow.setText(text);
            }
        });
    }


    @Override
    public void onError(String path, String log) {
        updateText(log);
    }

    @Override
    public void onReadAction(String path, String log) {
        updateText(log);
    }

    @Override
    public void onWriteAction(String path, String log) {
        updateText(log);
    }

    @Override
    public void onTestOver() {
        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    stopTest();
                }
            });
        }
    }

    @Override
    public void onDeleteOver() {
        String log = getString(R.string.engineer_hard_disk_delete_over);
        updateText(log);

        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    btnStart.setEnabled(true);
                    spinnerCount.setEnabled(true);
                    spinnerSize.setEnabled(true);
                    btnDelete.setEnabled(true);
                }
            });
        }
    }

    @Override
    public void onRWCompletedAction(String rootPath) {
        String log = "RW completed-> path = " + rootPath;
        updateText(log);
    }

    private void updateTempLog() {
        StorageManager sm = mContext.getSystemService(StorageManager.class);

        List<StorageVolume> volList = sm.getStorageVolumes();


        String log = getString(R.string.engineer_hard_disk_not_found);

        StringBuilder sb = new StringBuilder("");

        for (StorageVolume vol : volList) {
            if (!vol.isPrimary()) {
                int temp = getTemperature(sm, getVolumeId(vol));
                sb.append("path:" + getVolumePath(vol) + ", temp(C):" + temp);
                sb.append("\n");
            }
        }

        if (!TextUtils.isEmpty(sb.toString())) {
            log = (sb.toString());
        }

        updateText(log);

    }


    public String getVolumePath(StorageVolume volume) {
        try {
            if (volume.getState().equals(Environment.MEDIA_MOUNTED)) {
                Method getPath = StorageVolume.class.getMethod("getPath");
                String path = (String) getPath.invoke(volume);
                DebugLog.e("Storage Path--->" + path);

                return path;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    public String getVolumeId(StorageVolume volume) {

        try {

            Method getId = StorageVolume.class.getMethod("getId");
            String id = (String) getId.invoke(volume);
            DebugLog.e("Storage getId--->" + id);

            return id;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    public int getTemperature(StorageManager manager, String volId) {

        try {

            Method getTemperature = StorageManager.class.getMethod("getTemperature", String.class);
            int temp = (int) getTemperature.invoke(manager, volId);
            DebugLog.e("Storage getTemperature--->" + temp);

            return temp;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return -1;
    }

}
